
import {forIn, formatDate, guid} from './utils'
import {precheckEnd} from 'react-native-yuanxintrack/js/track';

function DurationTime (start, end) {
  this.startTime = start || Date.now()
  this.endTime = end || this.startTime
  this.finished = false

  this.duration = () => {
    return Math.max(0, this.endTime - this.startTime)
  }
}

function DurationInfo (name, type, ID) {
  this.name = name || `~Unknown~`
  this.type = type || `duration`
  this.ID = ID || guid()
  this.startTime = Date.now()
  this.backgroundTimes = []
  this.endTime = 0
  this.duration = 0
}

class DurationModule {
  static countDurationTime (info) {
    if (!info) { return }
    info.endTime = Date.now()
    let copyBackgroundTimes = info.backgroundTimes.slice(0) // 拷贝数组
    let durationTimeTop = copyBackgroundTimes.pop()
    if (durationTimeTop && !durationTimeTop.finished) { // finished 为 false 的话，可以说明还在后台
      durationTimeTop.endTime = info.endTime
    }
    if (durationTimeTop) {
      copyBackgroundTimes.push(durationTimeTop)
    }
    let duration = info.endTime - info.startTime
    forIn(copyBackgroundTimes, item => {
      if (item) {
        duration -= item.duration()
      }
    })
    info.duration = Math.max(0, duration)
    return {
      ...info,
      startTime: formatDate(new Date(info.startTime)),
      endTime: formatDate(new Date(info.endTime))
    }
  }

  constructor () {
    this.state = {}
    this._printLog = false
  }

  getState () {
    return this.state
  }

  getModule (ID) {
    return this.state[ID]
  }

  setSessionID (sessionID) {
    this.sessionID = sessionID
  }

  getSessionID () {
    return this.sessionID
  }

  // 开启 durationStart 状态
  durationStart (name, type, ID) {
    // 这里先不抛出异常
    // if (!name) { throw new Error('name should not be empty!') }
    const info = new DurationInfo(name, type, ID)
    this.state[info.ID] = info
    return info
  }

  // durationEnd 用来结束 durationStart 状态
  durationEnd (ID) {
    // 这里先不抛出异常
    // if (!ID) { throw new Error('ID should not be empty!') }
    const info = this.precheckEnd(ID)
    if (!info) { return }
    this.deleteTrackID(ID) // 计时结束，删除对象
    return info
  }

  // 预检、计算时长
  precheckEnd (ID) {
    // 这里先不抛出异常
    // if (!ID) { throw new Error('ID should not be empty!') }
    const info = this.getModule(ID)
    if (!info) { return }
    return DurationModule.countDurationTime(info)
  }

  // 开启 backgroundStart 状态
  backgroundStart (ID) {
    const info = this.getModule(ID)
    if (info) {
      info.backgroundTimes.push(new DurationTime())
    }
  }

  // backgroundEnd 用来结束 backgroundStart 状态
  backgroundEnd (ID, finished) {
    const info = this.getModule(ID)
    if (info) {
      // 假设不用在多线程场景下
      // 最顶部的就是最后一个即最近的后台时长对象，结束后台时长标志时认为最顶上的就是要操作的对象即还未结束 backgroundStart 状态的对象
      let durationTimeTop = info.backgroundTimes.pop() // 首先拿出来最顶上的后台时长对象
      if (durationTimeTop && !durationTimeTop.finished) {
        if (finished === true) {
          // 保证从 false --> true 只执行一次
          durationTimeTop.finished = true // finish后不再更新
        }
        durationTimeTop.endTime = Date.now()
      }
      if (durationTimeTop) {
        info.backgroundTimes.push(durationTimeTop) // 最后塞回到顶部去
      }
    }
  }

  deleteTrackID (ID) {
    if (__DEV__ && this._printLog) {
      console.log('before deleteTrackID ' + ID + ' state:' + JSON.stringify(this.state))
    }
    delete this.state[ID]
    if (__DEV__ && this._printLog) {
      console.log('after deleteTrackID ' + ID + ' state:' + JSON.stringify(this.state))
    }
  }
}

export const durationModule = new DurationModule()
